From f5297e6f4b9a3b4ff01f083c87e2637481490fc2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Timm=20B=C3=A4der?= Date: Sun, 1 Oct 2017 14:28:11 +0200 Subject: [PATCH] snapshot: Use one GPtrArray for all nodes Instead of creating one GPtrArray per GtkSnapshotState and saving nodes in there, create one GPtrArray per snapshot and assign a start_node_index to every GtkSnapshotState as well as a n_nodes variable so every state knows which nodes belong to it. --- gtk/gtksnapshot.c | 24 ++++++++++++++++++------ gtk/gtksnapshotprivate.h | 4 +++- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c index 0abc8813a9..3f95678c7a 100644 --- a/gtk/gtksnapshot.c +++ b/gtk/gtksnapshot.c @@ -90,14 +90,14 @@ gtk_snapshot_push_state (GtkSnapshot *snapshot, g_array_set_size (snapshot->state_stack, snapshot->state_stack->len + 1); state = &g_array_index (snapshot->state_stack, GtkSnapshotState, snapshot->state_stack->len - 1); - state->nodes = g_ptr_array_new_with_free_func ((GDestroyNotify) gsk_render_node_unref); - state->name = name; if (clip) state->clip_region = cairo_region_reference (clip); state->translate_x = translate_x; state->translate_y = translate_y; state->collect_func = collect_func; + state->start_node_index = snapshot->nodes->len; + state->n_nodes = 0; return state; } @@ -121,7 +121,6 @@ gtk_snapshot_get_previous_state (const GtkSnapshot *snapshot) static void gtk_snapshot_state_clear (GtkSnapshotState *state) { - g_ptr_array_unref (state->nodes); g_clear_pointer (&state->clip_region, cairo_region_destroy); g_clear_pointer (&state->name, g_free); } @@ -140,6 +139,7 @@ gtk_snapshot_init (GtkSnapshot *snapshot, snapshot->renderer = renderer; snapshot->state_stack = g_array_new (FALSE, TRUE, sizeof (GtkSnapshotState)); g_array_set_clear_func (snapshot->state_stack, (GDestroyNotify)gtk_snapshot_state_clear); + snapshot->nodes = g_ptr_array_new_with_free_func ((GDestroyNotify)gsk_render_node_unref); if (name && record_names) { @@ -978,10 +978,19 @@ gtk_snapshot_pop_internal (GtkSnapshot *snapshot) node = state->collect_func (snapshot, state, - (GskRenderNode **) state->nodes->pdata, - state->nodes->len, + (GskRenderNode **) snapshot->nodes->pdata + state->start_node_index, + state->n_nodes, state->name); + /* The collect func may not modify the state stack... */ + g_assert (state_index == snapshot->state_stack->len - 1); + + /* Remove all the state's nodes from the list of nodes */ + g_assert (state->start_node_index + state->n_nodes == snapshot->nodes->len); + g_ptr_array_remove_range (snapshot->nodes, + snapshot->nodes->len - state->n_nodes, + state->n_nodes); + g_array_remove_index (snapshot->state_stack, state_index); return node; @@ -1009,6 +1018,7 @@ gtk_snapshot_finish (GtkSnapshot *snapshot) result = gtk_snapshot_pop_internal (snapshot); g_array_free (snapshot->state_stack, TRUE); + g_ptr_array_free (snapshot->nodes, TRUE); return result; } @@ -1118,6 +1128,7 @@ gtk_snapshot_append_node (GtkSnapshot *snapshot, GskRenderNode *node) { GtkSnapshotState *current_state; + g_return_if_fail (snapshot != NULL); g_return_if_fail (GSK_IS_RENDER_NODE (node)); @@ -1125,7 +1136,8 @@ gtk_snapshot_append_node (GtkSnapshot *snapshot, if (current_state) { - g_ptr_array_add (current_state->nodes, gsk_render_node_ref (node)); + g_ptr_array_add (snapshot->nodes, gsk_render_node_ref (node)); + current_state->n_nodes ++; } else { diff --git a/gtk/gtksnapshotprivate.h b/gtk/gtksnapshotprivate.h index c9293765a6..1319df7d7b 100644 --- a/gtk/gtksnapshotprivate.h +++ b/gtk/gtksnapshotprivate.h @@ -32,7 +32,8 @@ typedef GskRenderNode * (* GtkSnapshotCollectFunc) (GtkSnapshot *snapshot, struct _GtkSnapshotState { char *name; - GPtrArray *nodes; + guint start_node_index; + guint n_nodes; cairo_region_t *clip_region; int translate_x; @@ -83,6 +84,7 @@ struct _GtkSnapshot { gboolean record_names; GskRenderer *renderer; GArray *state_stack; + GPtrArray *nodes; }; void gtk_snapshot_init (GtkSnapshot *state, -- 2.30.2